package org.onvivals.module.system.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.onvivals.common.exception.BusinessException;
import org.onvivals.common.param.PageParam;
import org.onvivals.common.web.PageResult;
import org.onvivals.module.system.entity.*;
import org.onvivals.module.system.mapper.SysUserMapper;
import org.onvivals.module.system.param.SysUserParam;
import org.onvivals.module.system.service.ISysMenuService;
import org.onvivals.module.system.service.ISysRoleService;
import org.onvivals.module.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Override
    public SysUser getByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return null;
        }
        SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
        return sysUser;
    }

    @Override
    public void checkUserIsEffective(SysUser sysUser) {
        //判断当前用户是否有效
        if (sysUser == null) {
            String message = "账号不存在";
            throw new BusinessException(message);
        }
        if (sysUser.getStatus() != 1) {
            String message = "账号被冻结";
            throw new BusinessException(message);
        }
    }

    @Override
    public SysUser getByUserId(Long loginId) {
        SysUser sysUserVo = this.getById(loginId);
        if (sysUserVo != null) {
            List<SysRole> sysRoleDTOS = sysRoleService.listByUserId(loginId);
            log.info("sysRoleDTOS:{}", sysRoleDTOS);
            sysUserVo.setRoles(sysRoleDTOS);
            List<SysMenu> sysMenuDTOS = sysMenuService.listMenuByUserId(loginId, null);
            log.info("sysMenuDTOS:{}", sysMenuDTOS);
            sysUserVo.setAuthorities(sysMenuDTOS);
        }
        log.info("sysUserVos:{}", sysUserVo);
        return sysUserVo;
    }

    @Override
    public PageResult<SysUser> pageRel(SysUserParam param) {
        PageParam<SysUser, SysUserParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        IPage<SysUser> list = this.page(page, page.getOrderWrapper());
        if (CollUtil.isNotEmpty(list.getRecords())) {
            list.getRecords().forEach(sysUserDTO -> {
                List<SysRole> sysRoleDTOS = sysRoleService.listByUserId(sysUserDTO.getUserId());
                sysUserDTO.setRoles(sysRoleDTOS);
            });
        }
        return new PageResult<>(list.getRecords(), page.getTotal());
    }

    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    @Override
    public SysUser saveOrUpdateUser(SysUser sysUserDTO) {
        long count = this.count(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, sysUserDTO));
        if (count > 0) {
            throw new BusinessException("账号已存在");
        }
        if (sysUserDTO.getUserId() == null) {
            //生成随机盐
            String salt = RandomUtil.randomString(10);
            String userPassword = SaSecureUtil.md5BySalt(sysUserDTO.getPassword(), salt);
            sysUserDTO.setSalt(salt);
            sysUserDTO.setPassword(userPassword);
        }
        SysUser user = BeanUtil.toBean(sysUserDTO, SysUser.class);
        user.setStatus(1);
        this.saveOrUpdate(user);
        List<SysRole> roles = sysUserDTO.getRoles();
        if (CollUtil.isNotEmpty(roles)) {
            Set<Long> roleIds = roles.stream().map(SysRole::getRoleId).collect(Collectors.toSet());
            log.info("角色ID:{}", roleIds);
            sysRoleService.saveBatchUserRole(user.getUserId(), roleIds);
        }
        return user;
    }

//    /**
//     * 批量查询用户的角色
//     *
//     * @param users 用户集合
//     */
//    private void selectUserRoles(List<SysUser> users) {
//        if (CollUtil.isNotEmpty(users)) {
//            List<Long> userIds = users.stream().map(SysUser::getUserId).collect(Collectors.toList());
//            List<SysRole> userRoles = sysRoleService.listByUserIds(userIds);
//            for (SysUser user : users) {
//                List<SysRole> roles = userRoles.stream().filter(d -> user.getUserId()==d.getUserId())
//                        .collect(Collectors.toList());
//                user.setRoles(roles);
//            }
//        }
//    }
}
